package data

import (
	"context"
	"time"

	"github.com/brocaar/chirpstack-api/go/v3/as"
	"github.com/brocaar/lorawan"
	"github.com/pkg/errors"
	"network/v3/internal/config"
	"network/v3/internal/models"
	"network/v3/internal/storage"
)

const applicationClientTimeout = time.Second

// ErrAbort is used to abort the flow without error
var ErrAbort = errors.New("nothing to do")

var (
	getDownlinkDataDelay time.Duration
	disableMACCommands   bool
)

// Setup configures the package.
func Setup(conf config.Config) error {
	getDownlinkDataDelay = conf.NetworkServer.GetDownlinkDataDelay
	disableMACCommands = conf.NetworkServer.NetworkSettings.DisableMACCommands

	return nil
}

type dataContext struct {
	ctx context.Context

	RXPacket                models.RXPacket
	MACPayload              *lorawan.MACPayload
	DeviceSession           storage.DeviceSession
	DeviceProfile           storage.DeviceProfile
	ServiceProfile          storage.ServiceProfile
	ApplicationServerClient as.ApplicationServerServiceClient
	MACCommandResponses     []storage.MACCommandBlock
	MustSendDownlink        bool
}

// Handle handles an uplink data frame
func Handle(ctx context.Context, rxPacket models.RXPacket) error {
	dataCtx := dataContext{
		ctx:      ctx,
		RXPacket: rxPacket,
	}

	return HandleRunTasks(&dataCtx)
}

func HandleRunTasks(dataCtx *dataContext) error {
	for _, task := range tasks {
		if err := task(dataCtx); err != nil {
			if err == ErrAbort {
				return nil
			}

			return err
		}
	}

	return nil
}
